import logging
import re
from argparse import ArgumentParser
from pathlib import Path

import coloredlogs
import httpx
import peewee as pw
import yaml

parser = ArgumentParser()  # 命令行参数
parser.add_argument('-l', default='info', help='日志等级')
cli_args = parser.parse_args()
log_level: str = cli_args.l  # 日志等级

# 启用彩色日志
coloredlogs.install(fmt='%(asctime)s %(levelname)s %(message)s', level=getattr(logging, log_level.upper()))
# 关闭不重要的日志
logging.getLogger('urllib3').setLevel(logging.FATAL)
logging.getLogger('chardet').setLevel(logging.INFO)
logging.getLogger('hpack').setLevel(logging.INFO)

config: dict = yaml.safe_load(Path('config.yaml').read_text())  # 从 config.yaml 读取数据库等配置

# 数据库连接对象
db = pw.MySQLDatabase(
    config['db']['name'], user=config['db']['user'], password=config['db']['password'], charset='utf8',
)
logging.info(f"数据库已连接: {config['db']['name']}")

request_headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3835.0 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
    'Accept-Language': 'en-US,en;q=0.5',
    'Accept-Encoding': 'gzip, deflate, br',
    'DNT': '1',
    'Connection': 'keep-alive',
    'Upgrade-Insecure-Requests': '1',
    'TE': 'Trailers',
    'Pragma': 'no-cache',
    'Cache-Control': 'no-cache',
}


# 数据库模型基类
class Model(pw.Model):
    class Meta:
        database = db
        only_save_dirty = True


# 网络请求基类
class Client(httpx.Client):
    def __init__(self):
        super().__init__(headers=request_headers, http2=True, timeout=10)

    # 发送请求
    def send_request(self, method, **kwargs) -> httpx.Response:
        headers = kwargs.setdefault('headers', {})
        headers['Host'] = re.search(r'^https?://(.+?)(/|$)', kwargs['url']).group(1)
        while True:
            logging.debug(kwargs['url'])
            try:
                response: httpx.Response = getattr(self, method)(**kwargs)
                return response
            except (httpx.RemoteProtocolError,):
                continue
            except Exception as e:
                logging.error(f'Exception: {type(e)}, {e}', exc_info=True)


client = Client()  # 公共对象
